package com.dy.yunying.biz.dao.datacenter.impl;

import com.dy.yunying.api.datacenter.vo.AdDataAnalysisVO;
import com.dy.yunying.api.dto.ConversionAnalysisDto;
import com.dy.yunying.api.dto.XingTuDataDTO;
import com.dy.yunying.api.vo.ConversionAnalysisVo;
import com.dy.yunying.api.vo.XingTuDataVO;
import com.dy.yunying.biz.config.YunYingProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Collection;
import java.util.List;

/**
 * @Description
 * @Author chengang
 * @Date 2022/3/1
 */
@Slf4j
@Component
public class ConversionAnalysisDao {

	private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder().appendPattern("yyyyMMdd").toFormatter();

	@Resource(name = "clickDcSessionTemplate")
	private JdbcTemplate clickhouseTemplate;

	@Resource
	private YunYingProperties yunYingProperties;

	/**
	 * 转化分析报表总数
	 *
	 * @param analysisDto
	 * @return
	 */
	public int selectConversionCount(ConversionAnalysisDto analysisDto) {
		final String countSqlStr = "";//this.getCountSqlBuilder(xingtu).toString();
		log.info("转化分析报表总数SQL: \n[{}]", countSqlStr);
		final Integer count = clickhouseTemplate.queryForObject(countSqlStr, (row, idx) -> requireInteger(row.getObject(1)));
		return null == count ? 0 : count;
	}

	/**
	 * 转化分析报表分页
	 *
	 * @param analysisDto 查询条件
	 * @param isPage 是否分页
	 * @return
	 */
	public List<ConversionAnalysisVo> selectConversionPage(ConversionAnalysisDto analysisDto, boolean isPage) {
		final String listSqlStr = "";
		log.info("转化分析报表分页SQL: \n[{}]", listSqlStr);
		return clickhouseTemplate.query(listSqlStr, xingtuObjectRelationMapping(analysisDto));
	}

	private String getCycleType(ConversionAnalysisDto analysisDto) {
		String cycleType;
		if (null == analysisDto.getCycleType()) {
			cycleType = "collect AS cycleType";
		} else if (1 == analysisDto.getCycleType()) {
			cycleType = "day AS cycleType";
		} else if (2 == analysisDto.getCycleType()) {
			cycleType = "week AS cycleType";
		} else if (3 == analysisDto.getCycleType()) {
			cycleType = "month AS cycleType";
		} else {
			cycleType = "collect AS cycleType";
		}
		return cycleType;
	}

	private RowMapper<ConversionAnalysisVo> xingtuObjectRelationMapping(ConversionAnalysisDto analysisDto) {
		return (rs, idx) -> {
			final ConversionAnalysisVo analysisVo = new ConversionAnalysisVo();
			Collection<String> groupBys = analysisDto.getGroupBys();
			analysisVo.setCycleType(rs.getString("cycleType"));
			if (groupBys.contains("investorId")) {
				analysisVo.setInvestorId(requireLong(rs.getObject("investorId"))).setInvestorName(rs.getString("investorName"));
			}
			if (groupBys.contains("parentchl")) {
				analysisVo.setParentchl(rs.getString("parentchl"));
			}
			if (groupBys.contains("deptId")) {
				analysisVo.setDeptId(requireLong(rs.getObject("deptId"))).setDeptName(rs.getString("deptName"));
			}
			if (groupBys.contains("pgid")) {
				analysisVo.setPgid(requireLong(rs.getObject("pgid"))).setPgname(rs.getString("pgname"));
			}
			if (groupBys.contains("gameid")) {
				analysisVo.setGameid(requireLong(rs.getObject("gameid")));
			}
			if (groupBys.contains("os")) {
				analysisVo.setOs(requireInteger(rs.getObject("os")));
			}

			analysisVo.setShownums(requireLong(rs.getLong("shownums")));
			analysisVo.setClickRatio(requireBigDecimal(rs.getBigDecimal("clickRatio"), 2));
			//TODO

			return analysisVo;
		};
	}

	private static Integer requireInteger(Object value) {
		if (null == value) {
			return null;
		}
		if (value instanceof Number) {
			return ((Number) value).intValue();
		}
		throw new NumberFormatException(value.getClass() + " 不可转换为 java.lang.Integer");
	}

	private static Long requireLong(Object value) {
		if (null == value) {
			return null;
		}
		if (value instanceof Number) {
			return ((Number) value).longValue();
		}
		throw new NumberFormatException(value.getClass() + " 不可转换为 java.lang.Long");
	}

	private static BigDecimal requireBigDecimal(BigDecimal value, int scala) {
		if (null == value) {
			return null;
		}
		return value.setScale(scala, RoundingMode.HALF_UP);
	}
}
